Skip to main content

Sidebar

Overriding Sidebar Component

You can override default sidebar component by providing DrawingsSidebarComponent or DrawingsSidebarFooter into uiOverrides: DrawingsSidebar prop to the ChartReactApp

The sidebar component has the following properties:

interface DrawingSidebarProps {
readonly drawingGroups: DrawingGroup[];
readonly onSidebarToggle: (isExpanded: boolean) => void;
readonly onButtonClick: (type: SidebarFooterButtonType) => void;
readonly onDrawingClick: (type: DrawingType) => void;
readonly buttonsState: ButtonsState;
readonly isSidebarExpanded: boolean;
readonly drawingsDisabled: boolean;
readonly onFavorite: (name: DrawingType) => void;
readonly onUnFavorite: (name: DrawingType) => void;
readonly favoriteDrawings: Array<DrawingType>;
readonly activeDrawingType: DrawingType | string;
readonly icons: IconsPool;
readonly startNewIconDrawing: (iconType: IconsPoolNames) => void;
}

The sidebar footer component has the following properties:

interface DrawingsSidebarFooterProps {
readonly buttonsState: ButtonsState;
readonly expanded: boolean;
readonly disabled?: boolean;
readonly onButtonClick: (type: SidebarFooterButtonType) => void;
}

Example

Sidebar changed drawings list and scrollable, Sidebar footer removed hide and sync buttons

Source code:

import { ChartReactAppContainer, ChartReactAppWrapper } from '../../../../src/components/ChartReactApp';
import { FlexContainer } from '../../../../src/components/FlexContainer';
import React, { memo, useCallback, useContext, useRef } from 'react';
import { DrawingSidebarProps } from '@dx-private/dxchart5-react/dist/chart/components/chart-sidebar/chart-drawings-sidebar.component';
import { OverrideProps, useIcons } from '@dx-private/dxchart5-react/dist/chart/ui-overrides';
import { CREATE_MOCK_PROVIDERS } from '@dx-private/dxchart5-react-mock-providers';
import { ChartReactAPI } from '@dx-private/dxchart5-react/dist/chart/view-models/api/chart-react-api.view-model';
import {
DrawingsSidebarFooter as DefaultDrawingsSidebarFooter,
DrawingsSidebarFooterProps,
} from '@dx-private/dxchart5-react/dist/chart/components/chart-sidebar/chart-drawings-sidebar-footer.component';
import { DrawingsSidebarHeader } from '@dx-private/dxchart5-react/dist/chart/components/chart-sidebar/chart-drawings-sidebar-header.component';
import { DrawingType, isDrawingType } from '@dx-private/dxchart5-react/dist/chart/model/drawing.model';
import { DrawingsSidebarDrawingIcon } from '@dx-private/dxchart5-react/dist/chart/components/chart-sidebar/components/chart-drawings-sidebar-drawing-icon.component';
import { DrawingsSidebarDrawing } from '@dx-private/dxchart5-react/dist/chart/components/chart-sidebar/components/chart-drawings-sidebar-drawing.component';
import { SidebarSeparatorStyled } from '@dx-private/dxchart5-react/dist/chart/components/chart-sidebar/components/chart-drawings-sidebar-separator.styled';
import { MultiChartComponentContext } from '@dx-private/dxchart5-react/dist/chart/components/multi-chart/multi-chart-context';
import {
SidebarFooterButtonType,
SidebarFooterButtonTypes,
} from '@dx-private/dxchart5-react/dist/chart/components/chart-sidebar/chart-sidebar.model';
import { useA11yListboxArrowsFocusController } from '@dx-private/dxchart5-react/dist/chart-kit/accessibility/use-a11y-listbox-arrows-focus-controller';
import { DrawingsSidebarButtonWithTooltip } from '@dx-private/dxchart5-react/dist/chart/components/chart-sidebar/components/chart-drawings-sidebar-button-with-tooltip.component';
import {
getSidebarFooterButtonName,
getSidebarFooterIconByType,
} from '@dx-private/dxchart5-react/dist/chart/components/chart-sidebar/footer-functions';
import { DrawingsSidebarFooterStyled } from '@dx-private/dxchart5-react/dist/chart/components/chart-sidebar/chart-drawings-sidebar-footer.styled';
export const DrawingsSidebarComponent = ({
chartReactAPIProps: _chartApi,
originalProps: props,
}: OverrideProps<DrawingSidebarProps>) => {
const isActiveDrawing = useCallback(
(type: string | number) => (!isDrawingType(props.activeDrawingType) ? false : props.activeDrawingType === type),
[props.activeDrawingType],
);
return (
<div
style={{
display: 'flex',
flexFlow: 'column',
justifyContent: 'space-between',
backgroundColor: 'black',
alignItems: 'center',
}}>
<DrawingsSidebarHeader
disabled={props.drawingsDisabled}
expanded={props.isSidebarExpanded}
onToggleExpanded={props.onSidebarToggle}
/>
<div style={{ overflowY: 'scroll', scrollbarWidth: 'none' }}>
{props.drawingGroups.map((group, i) => {
return (
<React.Fragment key={group.groupName}>
{group.drawings.map((type: DrawingType) => {
const favorite = props.favoriteDrawings.includes(type);
return type === 'icon' ? (
<DrawingsSidebarDrawingIcon
disabled={props.drawingsDisabled}
key={type}
icons={props.icons}
active={isActiveDrawing(type)}
expanded={props.isSidebarExpanded}
onSelectIcon={() => void 0}
/>
) : (
<DrawingsSidebarDrawing
key={type}
type={type}
disabled={props.drawingsDisabled}
active={isActiveDrawing(type)}
expanded={props.isSidebarExpanded}
favorite={favorite}
onSelect={() => void 0}
onAddToFavorites={() => void 0}
onRemoveFromFavorites={() => void 0}
/>
);
})}
{i === props.drawingGroups.length - 1 ? null : (
<SidebarSeparatorStyled role="separator" styles={{ height: 1 }} key={group.groupName} scrollTop={1} />
)}
</React.Fragment>
);
})}
</div>
<DefaultDrawingsSidebarFooter
disabled={props.drawingsDisabled}
expanded={props.isSidebarExpanded}
buttonsState={props.buttonsState}
onButtonClick={props.onButtonClick}
/>
</div>
);
};
/* remove HIDE and SYNC buttons from sidebar footer */
const sidebarFooterButtonTypes = [
'MAGNET',
'DRAWING_MODE',
// 'SYNC_DRAWINGS',
// 'HIDE_DRAWINGS',
'DELETE_DRAWINGS',
] as const;
const DrawingsSidebarFooter = memo((overrideProps: OverrideProps<DrawingsSidebarFooterProps>) => {
const { chartReactAPIProps: _chartApi, originalProps: props } = overrideProps;
const { expanded, disabled = false, onButtonClick, buttonsState } = props;
const iconsConfig = useIcons();
const { localization } = useContext(MultiChartComponentContext);
const footerListRef = useRef<HTMLDivElement>(null);
const isActive = useCallback(
(type: SidebarFooterButtonType) => {
switch (type) {
case SidebarFooterButtonTypes.DRAWING_MODE:
return buttonsState.drawingModeOn;
case SidebarFooterButtonTypes.MAGNET:
return buttonsState.magnetOn;
case SidebarFooterButtonTypes.HIDE_DRAWINGS:
return !buttonsState.drawingsVisible;
case SidebarFooterButtonTypes.DELETE_DRAWINGS:
return false;
case SidebarFooterButtonTypes.SYNC_DRAWINGS:
return buttonsState.drawingSyncEnabled;
}
},
[buttonsState],
);
useA11yListboxArrowsFocusController({
wrapperRef: footerListRef,
childrenSelector: 'li',
direction: 'vertical',
role: 'listbox',
});
const renderSidebarFooterToolbarItem = (type: SidebarFooterButtonType, supressSelect: boolean = false) => {
return (
<DrawingsSidebarButtonWithTooltip
key={type}
icon={getSidebarFooterIconByType(type, iconsConfig, buttonsState)}
label={getSidebarFooterButtonName(type, localization.sidebar, buttonsState)}
expanded={expanded}
onClick={() => !supressSelect && onButtonClick(type)}
disableTooltip={expanded}
disabled={disabled}
isActive={isActive(type)}
/>
);
};
return (
<>
<SidebarSeparatorStyled role="separator" styles={{ height: 1 }} scrollTop={1} />
<DrawingsSidebarFooterStyled
aria-orientation="vertical"
aria-label={localization.sidebar.a11y_footerList}
ref={footerListRef}
expanded={expanded}>
{sidebarFooterButtonTypes.map(type => renderSidebarFooterToolbarItem(type))}
</DrawingsSidebarFooterStyled>
</>
);
});
export const OverridingSidebarComponent = () => {
const onApiCreated = (api: ChartReactAPI) => {
api.onChartCreated((_chartId, _chartInstance) => {});
};
const chartReactAppContainerProps = { width: 800, height: 50 };
return (
<>
<ChartReactAppContainer {...chartReactAppContainerProps}>
<div className={'chart-react-container'} />
</ChartReactAppContainer>
<FlexContainer justifyContent={'flex-start'}>
<ChartReactAppWrapper
dependencies={{ ...CREATE_MOCK_PROVIDERS(), onApiCreated }}
uiOverrides={{
DrawingsSidebar: {
/* you can change both components at the same time, but you will have to add default footer component inside sidebar */
DrawingsSidebarComponent,
DrawingsSidebarFooter,
},
}}
/>
</FlexContainer>
</>
);
};